package com.xinting.piano.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.xinting.piano.R;
import com.xinting.piano.data.PColor;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by wuxinting on 15/10/30.
 */
public class PControlView extends View {

    /**
     * 提供的扩展control类型
     */
    private static Map<Integer, ICustomControlView> customControlViews;
    private Context context;
    private Paint paint;
    private Path pathToDraw;
    private Status status;
    private AtomicBoolean bPressed;
    private Integer nCustomType = -1;

    public PControlView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context, attrs);
    }

    /**
     * 初始化,获取xml中定义的默认几种类型
     *
     * @param context
     * @param attrs
     */
    private void initialize(Context context, AttributeSet attrs) {
        this.context = context;
        setStatus(Status.STOP);

        TypedArray types = context.obtainStyledAttributes(attrs, R.styleable.PControlView);
        for (int i = 0; i < types.getIndexCount(); i++) {
            switch (types.getIndex(i)) {
                case R.styleable.PControlView_status:
                    setStatus(Status.values()[types.getInteger(0, 3)]);
                    break;
                default:
                    setStatus(Status.STOP);
                    break;
            }
        }

        paint = new Paint();
        paint.setAntiAlias(true);

        pathToDraw = new Path();

        bPressed = new AtomicBoolean(false);

        customControlViews = new HashMap<>();
    }

    /**
     * 对外提供的自定义control添加
     *
     * @param customControlView
     */
    public void addCustomControlView(ICustomControlView customControlView) {
        if (customControlView != null && customControlView.getType() > 0) {
            customControlViews.put(customControlView.getType(), customControlView);
        }
    }

    /**
     * 获取播放控件的绘制路径
     *
     * @param len 绘制区域边长
     * @return
     */
    private Path getPathPlay(float len) {
        pathToDraw.reset();
        pathToDraw.moveTo(0, 0);
        pathToDraw.lineTo(len * 3 / 4, len / 2);
        pathToDraw.lineTo(0, len);
        pathToDraw.lineTo(0, 0);
        return pathToDraw;
    }

    /**
     * 获取上传控件的绘制路径
     *
     * @param len
     * @return
     */
    private Path getPathUpload(float len) {
        pathToDraw.reset();

        pathToDraw.moveTo(len / 2, 0);
        pathToDraw.lineTo(0, len / 3);
        pathToDraw.lineTo(len, len / 3);
        pathToDraw.lineTo(len / 2, 0);
        pathToDraw.addRect(len / 4, len / 2, len * 3 / 4, len, Path.Direction.CW);
        return pathToDraw;
    }

    @Override
    public void setClickable(boolean clickable) {
        super.setClickable(clickable);
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            bPressed.set(true);
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            bPressed.set(false);
        }
        invalidate();

        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int w = canvas.getWidth();
        int h = canvas.getHeight();
        float len = w > h ? h : w;
        float radius = len * 0.5f * 0.9f;

        drawBackground(canvas, len);

        radius *= 0.5f;

        switch (getStatus()) {
            case RECORD:
                canvas.drawCircle(len / 2, len / 2, radius, paint);
                break;
            case PLAY: {
                Path path = getPathPlay(radius * 2);
                //此处偏移量计算，根据getPathPlay中的Path计算得到，三角形中心(1/3x,1/2y)到矩形中心的偏移
                path.offset(len / 2 - radius / 2, len / 2 - radius);
                canvas.drawPath(path, paint);
            }
            break;
            case PAUSE:
                //竖线宽1/8，X偏移1/4+1/16
                canvas.drawRect(len * 5 / 16, len * 5 / 16, len * 7 / 16, len * 11 / 16, paint);
                canvas.drawRect(len * 9 / 16, len * 5 / 16, len * 11 / 16, len * 11 / 16, paint);
                break;
            case STOP:
                canvas.drawRect(len * 5 / 16, len * 5 / 16, len * 11 / 16, len * 11 / 16, paint);
                break;
            case UPLOAD: {
                Path path = getPathUpload(radius * 2);
                path.offset(len / 2 - radius, len / 2 - radius);
                canvas.drawPath(path, paint);
            }
                break;
            case CUSTOM: {
                ICustomControlView cV = customControlViews.get(getCustomType());
                if (cV != null) {
                    cV.draw(canvas, len, len, paint);
                }
            }
                break;
            default:
                break;
        }
    }

    /**
     * 画背景
     *
     * @param canvas
     */
    private void drawBackground(Canvas canvas, float len) {
        float radius = len * 0.5f * 0.9f;

        //background
        paint.setColor(PColor.SOFT_WHITE);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(len / 2, len / 2, radius, paint);

        //circle
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        if (bPressed.get() && isClickable()) {
            paint.setStrokeWidth(5);
        } else {
            paint.setStrokeWidth(1);
        }
        canvas.drawCircle(len / 2, len / 2, radius, paint);

        if (isClickable()) {
            paint.setColor(PColor.METAL_RED);
        } else {
            paint.setColor(getResources().getColor(android.R.color.darker_gray));
        }
        paint.setStyle(Paint.Style.FILL);
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
        invalidate();
    }

    /**
     * 获取所有的自定义类型
     *
     * @return
     */
    public Set<Integer> getCustomTypes() {
        return customControlViews.keySet();
    }

    public int getCustomType() {
        return nCustomType;
    }

    /**
     * 设置自定义类型
     *
     * @param type
     */
    public void setCustomType(int type) {
        this.nCustomType = type;
        invalidate();
    }

    /**
     * 默认的几种control类型
     */
    public enum Status {
        RECORD, PLAY, PAUSE, STOP, UPLOAD, CUSTOM
    }
}
